package com.sugeun.alarm;

import java.text.DateFormatSymbols;
import java.util.Calendar;

import android.content.Context;

public class Alarm {
	public static final String ALARM_ALERT_ACTION = "com.sugeun.alarm.ALARM_ALERT";
	public static final String ALARM_ALERT_KILL_ACTION = "com.sugeun.alarm.ALARM_ALERT_KILL";
	private int id = 0;//1
	private String hour = "";//2
	private String minutes = "";//3
	private String days_of_week = "";//4
	private int alarm_time = 0;//5
	private String enabled = "";//6
	private String message = "";//7
	private String vibrate = "";//8
	private String alert = "";//9 ring tone url
	
	public Alarm(int id, String hour, String minutes, String days_of_week, int alarm_time, String enabled, String message, String vibrate, String alert){
		this.id = id;
		this.hour = hour;
		this.minutes = minutes;
		this.days_of_week = days_of_week;
		this.alarm_time = alarm_time;
		this.enabled = enabled;
		this.message = message;
		this.vibrate = vibrate;
		this.alert = alert;
	}

	public int getId() {
		return id;
	}

	public String getHour() {
		return hour;
	}

	public String getMinutes() {
		return minutes;
	}

	public String getDays_of_week() {
		return days_of_week;
	}

	public int getAlarm_time() {
		return alarm_time;
	}

	public String getEnabled() {
		return enabled;
	}

	public String getMessage() {
		return message;
	}

	public String getVibrate() {
		return vibrate;
	}

	public String getAlert() {
		return alert;
	}
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////
	/*
     * Days of week code as a single int.
     * 0x00: no day
     * 0x01: Monday
     * 0x02: Tuesday
     * 0x04: Wednesday
     * 0x08: Thursday
     * 0x10: Friday
     * 0x20: Saturday
     * 0x40: Sunday
     */
    static final class DaysOfWeek {

        // Bitmask of all repeating days
        private int mDays;

        DaysOfWeek(int days) {
            mDays = days;
        }

        private boolean isSet(int day) {
            return ((mDays & (1 << day)) > 0);
        }

        public void set(int day, boolean set) {
            if (set) {
                mDays |= (1 << day);
            } else {
                mDays &= ~(1 << day);
            }
        }

        public void set(DaysOfWeek dow) {
            mDays = dow.mDays;
        }

        public int getCoded() {
            return mDays;
        }

        // Returns days of week encoded in an array of booleans.
        public boolean[] getBooleanArray() {
            boolean[] ret = new boolean[7];
            for (int i = 0; i < 7; i++) {
                ret[i] = isSet(i);
            }
            return ret;
        }

        public boolean isRepeatSet() {
            return mDays != 0;
        }

        /**
         * returns number of days from today until next alarm
         * @param c must be set to today
         */
        public int getNextAlarm(Calendar c) {
            if (mDays == 0) {
                return -1;
            }

            int today = (c.get(Calendar.DAY_OF_WEEK) + 5) % 7;

            int day = 0;
            int dayCount = 0;
            for (; dayCount < 7; dayCount++) {
                day = (today + dayCount) % 7;
                if (isSet(day)) {
                    break;
                }
            }
            return dayCount;
        }
    }
    
    
    static Calendar calculateAlarm(int hour, int minute, Alarm.DaysOfWeek daysOfWeek) {

        // start with now
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(System.currentTimeMillis());

        int nowHour = c.get(Calendar.HOUR_OF_DAY);
        int nowMinute = c.get(Calendar.MINUTE);

        // if alarm is behind current time, advance one day
        if (hour < nowHour  ||
            hour == nowHour && minute <= nowMinute) {
            c.add(Calendar.DAY_OF_YEAR, 1);
        }
        c.set(Calendar.HOUR_OF_DAY, hour);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);

        int addDays = daysOfWeek.getNextAlarm(c);
        /* Log.v("** TIMES * " + c.getTimeInMillis() + " hour " + hour +
           " minute " + minute + " dow " + c.get(Calendar.DAY_OF_WEEK) + " from now " +
           addDays); */
        if (addDays > 0) c.add(Calendar.DAY_OF_WEEK, addDays);
        return c;
    }
}
